#include "queue.h"
#include <stdlib.h>
#include <stdio.h>

Queue* initQueue(){
	Queue* newQueue = (Queue*)malloc(sizeof(Queue));
	if(newQueue == NULL) {
		return NULL;
	}
	else
	{
		newQueue->_headOfQueue = NULL;
		newQueue->_endOfQueue = NULL;
		newQueue->_size = 0;
		return newQueue;
	}

}

//this function insert a thread element into the queue according to its time stamp id
int addThreadToQueue(Queue* queue, Thread* thread){
	if(0){//(thread->_readyStartTime) == NULL){
		return 0;
	}
	else{
		Node* node = queue->_headOfQueue;
		Node* newNode = (Node*)malloc(sizeof(Node));
		if(newNode == NULL){
			return 0;
		}
		newNode->_data = thread;
		newNode->_next = NULL;
		//checking if this is the first link in the queue
		if(node == NULL){
			queue->_headOfQueue = newNode;
			return 1;
		}
		Node* previousNode;
		//checking for the index of insertion according to timeStamp
		while(node != NULL && node->_data->_readyTimeStamp < thread->_readyTimeStamp){//node != NULL &&  timercmp(&node->_data->_readyStartTime,&thread->_readyStartTime,<) != 0){
			previousNode = node;
			node = node->_next;
		}
		if(node == queue->_headOfQueue){
			queue->_headOfQueue = newNode;
			newNode->_next = node;
			return 1;
		}
		else{
			previousNode->_next = newNode;
			//if node == NULL then we've reached the end of the queue and the new node is added accordingly:
			if(node != NULL){
				newNode->_next = node;
			}
			return 1;
		}
	}
}

Thread* peekThreadPointerFromQueue(Queue* queue){
	if(queue->_headOfQueue == NULL){
		return NULL;
	}
	else{
		Thread* result =  queue->_headOfQueue->_data;
		return result;
	}
}

Thread* popThreadPointerFromQueue(Queue* queue){
	if(queue->_headOfQueue == NULL){
		return NULL;
	}
	else{
		Thread* result =  queue->_headOfQueue->_data;
		removeThreadFromQueue(queue,result);
		return result;
	}
}

int removeThreadFromQueue(Queue* queue, Thread* threadToRemove){
	Node* node = queue->_headOfQueue;
	if(node == NULL){
		return 0;
	}
	if(node->_data->_id == threadToRemove->_id){
		queue->_headOfQueue = node->_next;
		return 1;
	}
	else
	{
		while(node->_next!=NULL && node->_next->_data->_id != threadToRemove->_id){
			node = node->_next;
		}
		if(node->_next == NULL)
		{
			return 0;
		}
		else
		{
			Node* toRemove = node->_next;
			node->_next = node->_next->_next;
			free(toRemove);
			return 1;
		}
	}
}

//TODO: delete after tests
void printQueue(Queue* queue) {
	Node* node = queue->_headOfQueue;
	if(node == NULL){
		printf("Queue is empty\n");
	}
	else
	{
		while(node!=NULL){
			printf("%d -> ",node->_data->_id);
			node = node->_next;
		}
		printf("\n");
	}
}
